package org.jeecg.modules.third.openapi;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.LngLonUtil;
import org.jeecg.modules.third.openapi.dto.ParkInfo;
import org.jeecg.modules.third.openapi.dto.WaybillRoute;
import org.jeecg.modules.wlhy.hyvehicle.entity.HyVehicle;
import org.jeecg.modules.wlhy.hyvehicle.service.IHyVehicleService;
import org.jeecg.modules.wlhy.shipping.entity.PointDataListVO;
import org.jeecg.modules.wlhy.shipping.entity.WaybillRouteVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

@Slf4j
@Service
public class XDWaybillRouteService {


    @Autowired
    private XDOpenApiService xdOpenApiService;
    @Autowired
    private IHyVehicleService vehicleService;

    public WaybillRouteVO getShippingTrack(String vehicleNo, String startTime, String endTime) {

        log.info("获取信达轨迹,参数{} {} {} {}", vehicleNo, startTime, endTime);
        HyVehicle hyVehicle = vehicleService.getHyVehicleByVehicleNumber(vehicleNo);

        String vco = hyVehicle != null && StringUtils.isNotEmpty(hyVehicle.getVehiclePlateColorCode()) ? hyVehicle.getVehiclePlateColorCode() : "2";
        //中交轨迹和交通部字典值不一样，黄绿车牌交通部要求93，中交是3
        if ("93".equals(vco)) {
            vco = "3";
        }

        Date statusDtLoading = DateUtils.stringToDateTime(startTime);
        Date statusDtUnloading = DateUtils.stringToDateTime(endTime);
        int second = DateUtils.getDifferentDaysByMillisecond(statusDtLoading, statusDtUnloading);
        List<WaybillRoute> waybillRoutes = new ArrayList<>();
        List<ParkInfo> parkInfos = new ArrayList<>();
        WaybillRouteVO waybillRouteVO = new WaybillRouteVO();
        try {
            int days = 1;
            if (second > 86400*2) {
                BigDecimal diff = new BigDecimal(second*1000).divide(new BigDecimal(86400000*2),7, BigDecimal.ROUND_HALF_UP);
                days = (int) Math.ceil(diff.doubleValue());
            }

            if (days == 1) {
                String res = this.xdOpenApiService.getRouterPath(vehicleNo, vco, startTime, endTime);
                if (StringUtils.isNotEmpty(res)) {
                    JSONObject jsonObject = JSONObject.parseObject(res);
                    JSONObject result = jsonObject.getJSONObject("result");
                    if (result != null) {
                        String trackArray = result.getString("trackArray");
                        if (StringUtils.isNotEmpty(trackArray)){
                            waybillRoutes.addAll(JSONObject.parseArray(trackArray, WaybillRoute.class));
                        }
                    }
                }
            } else {
                double mileageDouble = 0;
                Set<String> errorMessages = new HashSet<>();
                for (int i = 1; i <= days; i++) {
                    Calendar calendar = new GregorianCalendar();
                    calendar.setTime(statusDtLoading);
                    //把日期往后增加三天.整数往后推,负数往前移动
                    calendar.add(Calendar.DATE, 2);
                    //这个时间就是日期往后推一天的结果
                    Date endDate = calendar.getTime();
                    String newEndTime = i == days ? DateUtils.dateTimeToString(statusDtUnloading) : DateUtils.dateTimeToString(endDate);
                    String newStartTime = DateUtils.dateTimeToString(statusDtLoading);
                    String res = null;
                    try {
                        res = this.xdOpenApiService.getRouterPath(vehicleNo, vco, newStartTime, newEndTime);
                    } catch (Exception ex) {
                        log.info("ZJHYWaybillRouteService  getRouterPath  vehicleNo|{}, vco|{}, startTime|{}, endTime |{} ,Exception |{}"
                                ,vehicleNo, vco, newStartTime, newEndTime,ex.getMessage());

                        errorMessages.add( ex.getMessage() );

                    }
                    if (StringUtils.isNotEmpty(res)) {
                        JSONObject jsonObject = JSONObject.parseObject(res);
                        JSONObject result = jsonObject.getJSONObject("result");
                        if (result != null) {
                            String trackArray = result.getString("trackArray");
                            if (StringUtils.isNotEmpty(trackArray)){
                                waybillRoutes.addAll(JSONObject.parseArray(trackArray, WaybillRoute.class));
                            }
                        }

                    }
                    statusDtLoading = endDate;
                }

                waybillRouteVO.setMileage(String.valueOf(mileageDouble));
                if (CollectionUtils.isEmpty(waybillRoutes) && errorMessages.size() > 0  ) {
                    throw new JeecgBootException( StringUtils.join(errorMessages,","));
                }
            }
        } catch (Exception e) {
            log.info("ZJHYWaybillRouteService  getRouterPath  Exception |{}", e.getMessage());
            throw new JeecgBootException(e.getMessage());
        }
        Map<String,ParkInfo > parkInfoMaps = new HashMap<>();
        if (CollectionUtils.isNotEmpty(parkInfos)) {
            for(ParkInfo parkInfo : parkInfos){
                parkInfoMaps.put(parkInfo.getParkLon()+"_"+parkInfo.getParkLat(),parkInfo);
            }
        }

        if (CollectionUtils.isNotEmpty(waybillRoutes)) {

            List<PointDataListVO> pointDataListVOs = new ArrayList();
            List<List<String>> valueList = new ArrayList<>();
            List<ParkInfo> parkInfoList =  new ArrayList<>();
            for (WaybillRoute waybillRoute : waybillRoutes) {

                PointDataListVO pointDataListVO = new PointDataListVO();
                //Double.parseDouble(waybillRoute.getSpd())
                Double spd = Double.valueOf(waybillRoute.getSpd());
                pointDataListVO.setCs(spd);

                double lat = Double.valueOf(waybillRoute.getLat()) / 600000;
                double lan = Double.valueOf(waybillRoute.getLon()) / 600000;
                double[]  gcj02 = LngLonUtil.gps84_To_Gcj02(lat, lan);

                pointDataListVO.setLat(String.valueOf(gcj02[0]));
                pointDataListVO.setLng(String.valueOf(gcj02[1]));

                String gtm = waybillRoute.getGtm().replace("/", "");
                String strGtm = DateUtils.strDateTimeToFormatString(gtm);
                pointDataListVO.setReceiveTime(strGtm);
                //停车信息
                if(parkInfoMaps.size() > 0){
                    String key = waybillRoute.getLon()+"_"+waybillRoute.getLat();
                    if(parkInfoMaps.get(key) != null){

                        for(ParkInfo parkInfo : parkInfos){

                            String key1 = parkInfo.getParkLon()+"_"+parkInfo.getParkLat();
                            if(key1.equals(key)){
                                String parkBte  =  StringUtils.isNotBlank(parkInfo.getParkBte()) ?  DateUtils.timestamptoStr2( Long.valueOf(parkInfo.getParkBte() )) : "";
                                String parkEte  =  StringUtils.isNotBlank(parkInfo.getParkEte()) ?  DateUtils.timestamptoStr2( Long.valueOf(parkInfo.getParkEte() )) : "";

                                parkInfo.setParkBte( parkBte );
                                parkInfo.setParkEte( parkEte );
                                parkInfo.setParkLon(String.valueOf(gcj02[1]));
                                parkInfo.setParkLat(String.valueOf(gcj02[0]));
                                parkInfoList.add(parkInfo);

                                pointDataListVO.setParkAdr(parkInfo.getParkAdr());
                                pointDataListVO.setParkBte( parkBte );
                                pointDataListVO.setParkEte( parkEte );
                                pointDataListVO.setParkLon(String.valueOf(gcj02[1]));
                                pointDataListVO.setParkLat(String.valueOf(gcj02[0]));
                                pointDataListVO.setParkMins(parkInfo.getParkMins());
                            }
                        }
                    }
                }

                pointDataListVOs.add(pointDataListVO);

                List<String> valueListString = new ArrayList<>();
                valueListString.add(String.valueOf(gcj02[1]));
                valueListString.add(String.valueOf(gcj02[0]));
                valueList.add(valueListString);
            }

            waybillRouteVO.setParkInfoList(parkInfoList);
            waybillRouteVO.setLineArray(valueList);
            waybillRouteVO.setPointDataList(pointDataListVOs);
        }

        return waybillRouteVO;

    }
}
